using NUnit.Framework;
using ValidationFramework;

namespace ExampleLibraryCSharp.BusinessBaseClasses
{ 
	public class DataErrorInfoValidatableBaseLambdaExample
	{
		#region Example
		public class Person : DataErrorInfoValidatableBase
		{
			#region Fields

			private string firstName;
			private string lastName;
			private string emailAddress;

			#endregion


			#region Constructor

			public Person()
			{
				PropertyValidationManager.ValidateAll();
			}

			#endregion


			#region Properties

			[RequiredStringRule]
			[LengthStringRule(4)]
			public string FirstName
			{
				get
				{
					return firstName;
				}
				set
				{
					if (firstName != value)
					{
						firstName = value;
						ValidateProperty(() => FirstName);
					}
				}
			}


			[RequiredStringRule]
			[LengthStringRule(50, Minimum = 2)]
			public string LastName
			{
				get
				{
					return lastName;
				}
				set
				{
					if (lastName != value)
					{
						lastName = value;
						ValidateProperty(() => LastName);
					}
				}
			}


			[RequiredStringRule]
			[RegexValidatorAttribute(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*",
				ErrorMessage = "Invalid email format.")]
			[LengthStringRule(50)]
			public string EmailAddress
			{
				get
				{
					return emailAddress;
				}
				set
				{
					if (emailAddress != value)
					{
						emailAddress = value;
						ValidateProperty(() => EmailAddress);
					}
				}
			}


			#endregion
		}

		[TestFixture]
		public class ExampleUsage
		{
			[Test]
			public void RunIsValid()
			{
				var person = new Person();

				// Initially not valid
				Assert.IsFalse(person.IsValid);

				// Set FirstName, LastName and EmailAddress
				person.FirstName = "John";
				person.LastName = "Smith";
				person.EmailAddress = "John.Smith@email.com";

				// It is now valid
				Assert.IsTrue(person.IsValid);
			}


			[Test]
			public void RunValidatorResultsInError()
			{
				var person = new Person();
				// Initially there should be 3 items in ValidatorResultsInError as only 3 
				// properties have required rules.
				Assert.AreEqual(3, person.ValidatorResultsInError.Count);

				// Set LastName to a value and count goes down to 2
				person.LastName = "Smith";
				// No need to call IsValid (to force a validation) because properties are 
				// validated during each set
				Assert.AreEqual(2, person.ValidatorResultsInError.Count);
			}


			[Test]
			public void RunSpecificProperty()
			{
				var person = new Person();

				// LastName initially has an ErrorMessage because it is invalid
				var lastNameErrorMessage = person.GetError(() => person.LastName);
				Assert.IsNotNull(lastNameErrorMessage);

				// Set LastName and it will then have no ErrorMessage
				person.LastName = "Smith";
				// No need to call IsValid (to force a validation) because properties are 
				// validated during each set
				lastNameErrorMessage = person.GetError(() => person.LastName);
				Assert.IsEmpty(lastNameErrorMessage);
			}

		}
		#endregion
	}
}